home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dirut / chmod2.zip / CHMOD.C next >
Text File  |  1987-01-15  |  5KB  |  204 lines

  1. /*//////////////////////////////////////////////////////////////////////////
  2. // c h m o d . c 
  3. ////////////////
  4. CHMOD(1)                    MS DOS USER COMMANDS                    CHMOD(1)
  5.  
  6. NAME 
  7.         chmod
  8.  
  9. SYNOPSIS 
  10.         chmod [=+-][r][h][s][a] file ...
  11.  
  12. DESCRIPTION 
  13.     
  14.          Changes the attributes of 'file'. The file attributes can either 
  15.     be set (=),  or attributes can  be added (+)  or removed (-) from the
  16.     the current attribute. If no attributes  are specified, then the file
  17.     is marked 'normal' i.e. no attributes set except the archive bit.
  18.  
  19. Newman Lab        cohler@tcgould.tn.cornell.edu
  20. Cornell Univ      jbvy@cornella.bitnet
  21. Ithaca NY 14853    
  22.  
  23. I retain all rights to this program.         (c) Gene Cohler, January 1987
  24. **************************************************************************/
  25. /*
  26.  *  N.B. I use tab set to 4 
  27.  *
  28.  * History :
  29.  *  
  30.  *    Feb 14 1986    - Version 1 peeks out the window ...
  31.  *  
  32.  * Modified 
  33.  *     :- August 1 1986
  34.  *            1) Looks more like unix version - choose to set attribute
  35.  *               = or - or + to set or remove or add.
  36.  *             2) Talks a little more .. old age maybe !
  37.  *     :- January 1987
  38.  *            1) Default works a little better - now Archive set is default.
  39.  *                Also chmod file will set the archive bit only.
  40.  *            2) Ready to hit the streets with v 1.0
  41.  *            3) Directory Bugfix made, +- didnt work only =. Fixed.
  42.  *****************************************************************************
  43.  * Written in Microsoft C v 4.0. Should be linked together with ssetargv.obj
  44.  * included in the standard library
  45.  *****************************************************************************/
  46. #include <stdio.h>
  47. #include <dos.h>
  48.  
  49. #define        SET        1
  50. #define        GET        0
  51. #define        SUBDIR    0x10
  52. #define     ARCHIVE    0x20
  53.  
  54. main(argc,argv)
  55.     int argc; 
  56.     char **argv;
  57.     {
  58.     unsigned attrib = ARCHIVE ;
  59.     unsigned oldattrib=0 ;
  60.     unsigned newattrib=0 ;
  61.     static int what='=' ;
  62.     
  63.     register unsigned i  ;
  64.     register unsigned notfile ;
  65.  
  66.     if( argc == 1 )                               
  67.         error("No file specified");
  68.  
  69.    /*
  70.     * Find what attributes are being called for
  71.     */
  72.  
  73.     for(i=1;i<argc;i++)
  74.         {
  75.         switch( argv[i][0] )
  76.             {
  77.             case '-' :
  78.             case '+' :
  79.             case '=' :
  80.                 parse(&attrib, argv[i], &what);
  81.                 notfile = i ;
  82.             }
  83.         }                       
  84.  
  85.    /*
  86.       * Now set em one by one 
  87.     */
  88.  
  89.     for( i=1; i<argc ; i++)
  90.         {
  91.         if( i != notfile )
  92.             {
  93.             oldattrib = mode( argv[i], attrib, GET) ;
  94.             /*
  95.              * Directory attrib not settable
  96.              */
  97.             if (oldattrib & SUBDIR)
  98.                 oldattrib = (oldattrib & (~SUBDIR) ) & 0xff ;
  99.             switch( what )
  100.                 {
  101.                 case '=' :    
  102.                     newattrib = attrib ;
  103.                     break;
  104.                 case '+' :    
  105.                     if(oldattrib == -1)
  106.                         {
  107.                         fprintf(stderr,"Error finding mode of %s\n",argv[i]);
  108.                         continue ;
  109.                         }
  110.                     newattrib = oldattrib | attrib ;
  111.                     break ;
  112.                 case '-' :
  113.                     if(oldattrib  == -1)
  114.                         {
  115.                         fprintf(stderr,"Error finding mode of %s\n",argv[i]);
  116.                         continue ;
  117.                         }
  118.                     newattrib = (oldattrib & (~attrib))  & 0xff;
  119.                     break;
  120.                 default :
  121.                     error("No mode qualifier given");
  122.                 }
  123.             if((oldattrib = mode( argv[i], newattrib, SET)) == -1)
  124.                 {
  125.                 fprintf(stderr,"Error setting mode of %s\n",argv[i]);
  126.                 continue ;
  127.                 }
  128.             }
  129.         }            
  130.     }        
  131.  
  132.     
  133. /******************************************** 
  134.  * mode.c  - change/get the mode - DOS call *
  135.  * action is 1 to set the mode :
  136.  * action is 0 to get the mode ;
  137.  *****************************************/
  138.  
  139. #define  SYSCALL    0x21  
  140.  
  141.     int 
  142. mode(name, attrib, action )
  143.     unsigned char name[]       ;
  144.     unsigned attrib                 ;
  145.     int action ;
  146.     {
  147.     struct SREGS segregs     ;
  148.     union REGS regs         ;
  149.  
  150.     if( action == SET)    regs.x.ax = 0x4301     ;/* Set up for a chmod */
  151.     else                regs.x.ax = 0x4300    ;
  152.     regs.x.cx = attrib      ;        
  153.     segread(&segregs)       ;                       /* get current ds value */
  154.     regs.x.dx = (unsigned int) name;             /* name is in ds:dx */
  155.     regs.x.cflag = 0        ;                    /* Make sure flag is zeroed */
  156.  
  157.     int86x(SYSCALL, ®s, ®s, &segregs) ;      /* Do it */
  158.  
  159.     if (regs.x.cflag)    return (-1) ;            /* Return error */
  160.     else                 return (regs.x.cx);        /* Return attrib */
  161.     } 
  162.  
  163. /*
  164.  *  Attributes used in the file descriptor 
  165.  */
  166.  
  167. #define    NORMAL        0x00
  168. #define    READONLY    0x01
  169. #define    HIDDEN        0x02
  170. #define    SYSTEM        0x04
  171. #define    VOLUME        0x08
  172.  
  173. parse( attrib, arg, what)
  174.     unsigned *attrib ;
  175.     char arg[]   ;
  176.     int *what    ;
  177.     {
  178.     register i ;
  179.     unsigned numargs = strlen(arg) ;
  180.     *attrib = NORMAL ;
  181.     *what = arg[0] ;
  182.  
  183.     if (numargs == 1)        /* Set Archive as Default */
  184.         {
  185.         *attrib = ARCHIVE ;
  186.         return ;
  187.         }
  188.     for(i=1; i<numargs ; i++)
  189.         {                                            
  190.         if( toupper(arg[i]) == 'R' )    *attrib |= READONLY ; 
  191.         if( toupper(arg[i]) == 'S' )    *attrib |= SYSTEM ; 
  192.         if( toupper(arg[i]) == 'A' )    *attrib |= ARCHIVE ;
  193.         if( toupper(arg[i]) == 'H' )    *attrib |= HIDDEN ;
  194.         }
  195.     }  
  196.  
  197. error(msg)
  198.     char *msg;
  199.     {
  200.     fprintf(stderr,"Error: %s\n", msg);
  201.     fprintf(stderr,"Usage: chmod [+-=][rhsa] file(s)");
  202.     exit(1) ;
  203.     }
  204.